using System;
using System.Collections.Generic;
using System.Net;
using System.Diagnostics;

namespace TALoaders
{
    class YahooDownloader : BaseLoader
    {
        #region Private Members
        private System.Globalization.CultureInfo usCultureM = new System.Globalization.CultureInfo("en-US");
        private string urlHistDataTmplM = "http://ichart.finance.yahoo.com/table.csv?s=[ticker]&a=" +
                                            "[startMonth]&b=[startDay]&c=[startYear]&d=[endMonth]&e=" +
                                            "[endDay]&f=[endYear]&g=[freq]&ignore=.csv";
        private string urlQuoteTmplM = "http://quote.yahoo.com/d/quotes.csv?s=[ticker]&f=[tags]";

        private WebClient webClientM = new WebClient();
        private TraceSwitch traceM = new TraceSwitch("YahooLoader", "Debug messages in YahooLoader");
        #endregion

        #region Public Methods
        public YahooDownloader()
            : base(Loader.Yahoo)
        { }

        ~YahooDownloader()
        {
            webClientM.Dispose();
        }

        override public SortedList<DateTime, Quote> getHistoricalPrices(string ticker, DateTime startDate, DateTime endDate)
        {
            // --->> prepare URL <<---
            // NOTE: Yahoo's scheme uses a month number 1 less than actual e.g. Jan. ="0"
            int strtMo = startDate.Month - 1;
            string startMonth = strtMo.ToString();
            string startDay = startDate.Day.ToString();
            string startYear = startDate.Year.ToString();
            int endMo = endDate.Month - 1;
            string endMonth = endMo.ToString();
            string endDay = endDate.Day.ToString();
            string endYear = endDate.Year.ToString();

            string url = urlHistDataTmplM.Replace("[ticker]", ticker);
            url = url.Replace("[startMonth]", startMonth);
            url = url.Replace("[startDay]", startDay);
            url = url.Replace("[startYear]", startYear);
            url = url.Replace("[endMonth]", endMonth);
            url = url.Replace("[endDay]", endDay);
            url = url.Replace("[endYear]", endYear);
            url = url.Replace("[freq]", "d");   // possibly m,y

            // --->> Download Data <<---
            Debug.WriteLineIf(traceM.TraceInfo, url);
            string history = webClientM.DownloadString(url);

            // --->> Parse table <<---
            history = history.Replace("\r", "");        // trim off unused characters from end of line
            string[] rows = history.Split('\n');        // split to array on end of line
            string[] colNames = rows[0].Split(',');     // split column names: 0.Date, 1.Open, 2.High, 3.Low, 4.Close, 5.Volume, 6.Adj Close

            int nOfRows = rows.Length - 2;  // 2 rows unused (the first with names and the last which is empty)
            SortedList<DateTime, Quote> result = new SortedList<DateTime, Quote>(nOfRows);
            string[] rowData;

            for (int i = 0; i < nOfRows; ++i)
            {
                rowData = rows[nOfRows - i].Split(',');   // rows are in reverse order in Yahoo
                // 0:Date, 1:Open, 2:High, 3:Low, 4:Close, 5:Volum, 6:AdjClose
                DateTime date = Convert.ToDateTime(rowData[0], usCultureM);
                double open = Convert.ToDouble(rowData[1], usCultureM); ;
                double high = Convert.ToDouble(rowData[2], usCultureM);
                double low = Convert.ToDouble(rowData[3], usCultureM);
                double close = Convert.ToDouble(rowData[4], usCultureM);
                double volume = Convert.ToDouble(rowData[5], usCultureM);
                double adjClose = Convert.ToDouble(rowData[6], usCultureM);
                Quote quote = new Quote(open, high, low, close, volume, adjClose);

                result.Add(date, quote);
            }
            return result;
        }
  
        override public double getLastPrice(string ticker, out string timeStamp)
        {
            // for full list of tags see: http://www.gummy-stuff.org/Yahoo-data.htm
            Debug.WriteLineIf(traceM.TraceInfo, "Yahoo.getLastPrice(" + ticker + ")");
            string url = urlQuoteTmplM.Replace("[tags]", "l1").Replace("[ticker]", ticker);
            Debug.WriteLineIf(traceM.TraceVerbose, "lastPriceURL: " + url);
            string sLastTrade = webClientM.DownloadString(url).Replace("\r", "").Replace("\n", "");

            url = urlQuoteTmplM.Replace("[tags]", "t1").Replace("[ticker]", ticker);
            Debug.WriteLineIf(traceM.TraceInfo, "timeStampURL: " + url);
            timeStamp = webClientM.DownloadString(url).Replace("\r", "").Replace("\n", "");

            return Convert.ToDouble(sLastTrade, usCultureM);
        }
        #endregion 
    }
}
